//用户小仓库
import { defineStore } from "pinia";
//引入接口及数据类型
import { reqLogin, reqLogout, reqUserInfo } from "@/api/user";
import type { UserState } from "@/store/modules/types/type";
//引入本地存储工具方法
import { SET_TOKEN, GET_TOKEN, DEL_TOKEN } from "@/utils/token";
//引入路由
import { constantRoute, asyncRoutes, anyRoutes } from "@/router/routes";
//引入深拷贝方法，用于解决计算权限路由时会更改路由文件对象问题（原理就是复制一份去计算过滤）,需要先安装lodash
//@ts-ignore
import cloneDeep from "lodash/cloneDeep";
//引入路由，用于追加路由
import router from "@/router";

//计算用户拥有权限的路由
const filterUserRoutes = (asyncRoutes: any[], userRoutesName: any[] = []) => {
  return asyncRoutes.filter((item: any) => {
    if (userRoutesName.includes(item.name)) {
      //递归判断子路由
      if (item.children && item.children.length > 0) {
        item.children = filterUserRoutes(item.children, userRoutesName);
      }
      return true;
    }
  });
};

//过滤出所有静态路由的name，用于重置路由
const filterConstantRoutesName = (routes: any[], initArr: any[]) => {
  //@ts-ignore
  return routes.reduce((prev: any, route: any) => {
    initArr.push(route.name);
    if (route.children && route.children.length > 0) {
      filterConstantRoutesName(route.children, initArr);
    }
    return initArr;
  }, []);
};

let useUserStore = defineStore("User", {
  state: (): UserState => {
    return {
      token: GET_TOKEN(), //用户唯一标识token
      menuRoutes: constantRoute, //初始化存入常量路由，给菜单组件遍历生成
      userDetail: null, //用户详细信息
    };
  },
  actions: {
    //用户登录方法
    async userLogin(data: any) {
      let result: any = await reqLogin(data);
      if (result.code == 200) {
        this.token = result.data;
        SET_TOKEN(result.data);
        //保证async返回一个成功的promise
        return "ok";
      } else {
        return Promise.reject(new Error(result.data));
      }
    },
    //获取用户信息方法,TOKEN通过axios拦截器中发送header头实现，否则无法获取用户信息
    async userInfo() {
      //判断当前用户是否登录，如果未登录，跳转到登录页面
      let result: any = await reqUserInfo();
      if (result.code == 200) {
        result.data.username = result.data.name; //加这一句是因为真实接口中没有username字段，模板会报错，因此做一个转换
        this.userDetail = result.data;
        //获取用户信息成功后，计算出该用户所拥有权限的菜单，并追加给仓库和追加注册路由
        const userRoutes = filterUserRoutes(
          cloneDeep(asyncRoutes),
          result.data.routes,
        );
        this.menuRoutes = [...constantRoute, ...userRoutes, anyRoutes];
        [...userRoutes, anyRoutes].forEach((route: any) => {
          router.addRoute(route);
        });
        return "ok";
      } else {
        return Promise.reject(new Error("用户信息失效，请重新登陆"));
      }
    },
    //退出登录方法,清除所有跟用户有关的仓库数据及本地存储数据
    async logOut() {
      try {
        let response = await reqLogout();
        let result: any = DEL_TOKEN();
        this.userDetail = "";
        this.token = "";
        //重要：重置路由，否则路由信息缓存导致菜单权限出现BUG
        //如果是pc端，最好退出登陆后强制刷新浏览器一次更佳
        let routers = router.getRoutes();
        let constantRouteNames: any = filterConstantRoutesName(
          constantRoute,
          [],
        );
        constantRouteNames.push(anyRoutes.name);
        routers.map((it: any) => {
          if (!constantRouteNames.includes(it.name)) {
            router.removeRoute(it.name);
          }
        });

        if (response.code == 200 && result == undefined) {
          return "ok";
        } else {
          return Promise.reject(new Error("退出登陆失败,请稍后重试"));
        }
      } catch (error) {
        return Promise.reject(new Error("退出登录请求失败,请稍后重试"));
      }
    },
  },
  getters: {},
});

export default useUserStore;
//以下是接口返回示例
/*
登陆成功
{
  "code": 200,
  "message": "成功",
  "data": "eyJhbGciOiJIUzUxMiIsInppcCI6IkdaSVAifQ.H4sIAAAAAAAAAKtWKi5NUrJSCjAK0A0Ndg1S0lFKrShQsjI0s7QwsTA0MTDXUSotTi3yTAGKQZh-ibmpQB2JKbmZeUq1AJAsH85BAAAA.c72-vy2QgmzaGOUy_f5oXCUF0Q-WhNv6O1BjAB-BS0YYkmeHe3QvKTdtfs569cJKEahtBktiaW-WxUla-ROV1w",
  "ok": true
}
登陆失败
{
    "code": 201,
    "message": "失败",
    "data": "密码错误",
    "ok": false
}

获取用户成功
{
    "code": 200,
    "message": "成功",
    "data": {
        "routes": [
            "aaa",
            "User",
            "Category",
            "Discount",
            "ActivityEdit",
            "CouponRule",
            "Label",
            "Product",
            "Activity",
            "CouponAdd",
            "Trademark",
            "test1",
            "Attr",
            "ActivityAdd",
            "CouponEdit",
            "OrderShow",
            "111",
            "Permission",
            "Spu",
            "UserList",
            "ClientUser",
            "Order",
            "33",
            "t't",
            "Coupon",
            "permision",
            "Acl",
            "ActivityRule",
            "Role",
            "RoleAuth",
            "222",
            "Refund",
            "1223",
            "x",
            "Level",
            "OrderList",
            "Sku"
        ],
        "buttons": [
            "cuser.detail",
            "cuser.update",
            "cuser.delete",
            "btn.User.add",
            "btn.User.remove",
            "btn.User.update",
            "btn.User.assgin",
            "btn.Role.assgin",
            "btn.Role.add",
            "btn.Role.update",
            "btn.Role.remove",
            "btn.Permission.add",
            "btn.Permission.update",
            "btn.Permission.remove",
            "btn.Activity.add",
            "btn.Activity.update",
            "btn.Activity.rule",
            "btn.Coupon.add",
            "btn.Coupon.update",
            "btn.Coupon.rule",
            "btn.OrderList.detail",
            "btn.OrderList.Refund",
            "btn.UserList.lock",
            "btn.Category.add",
            "btn.Category.update",
            "btn.Category.remove",
            "btn.Trademark.add",
            "btn.Trademark.update",
            "btn.Trademark.remove",
            "btn.Attr.add",
            "btn.Attr.update",
            "btn.Attr.remove",
            "btn.Spu.add",
            "btn.Spu.addsku",
            "btn.Spu.update",
            "btn.Spu.skus",
            "btn.Spu.delete",
            "btn.Sku.updown",
            "btn.Sku.update",
            "btn.Sku.detail",
            "btn.Sku.remove",
            "btn.all",
            "tuiguang",
            "btn.test.2",
            "cars",
            "Cart-Add",
            "aaabbb",
            ""
        ],
        "roles": [
            "tf",
            "超级管理员"
        ],
        "name": "admin",
        "avatar": "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif",
        "username": "admin"
    },
    "ok": true
}

退出登录成功与获取用户成功一致


*/
